home *** CD-ROM | disk | FTP | other *** search
- {$m 8000,60000,230000}
- uses crt,dos,modunit;
- const
- col_backr = 0;
- col_backg = 0;
- col_backb = 10;
- col_back = 2;
-
- per_txt : array[0..48] of string[3] = (' ',
- 'C-1','C#1','D-1','D#1','E-1','F-1',
- 'F#1','G-1','G#1','A-1','A#1','B-1',
- 'C-2','C#2','D-2','D#2','E-2','F-2',
- 'F#2','G-2','G#2','A-2','A#2','B-2',
- 'C-3','C#3','D-3','D#3','E-3','F-3',
- 'F#3','G-3','G#3','A-3','A#3','B-3',
- 'C-4','C#4','D-4','D#4','E-4','F-4',
- 'F#4','G-4','G#4','A-4','A#4','B-4');
- hex_tbl : array[0..15] of char = ('0','1','2','3','4','5','6','7',
- '8','9','A','B','C','D','E','F');
- fx_txt : array[0..15] of string[3] = ( {downcase means fx not}
- 'ARP','PR^','PRv','TON','vib','T&S', {correctly supported}
- 'V&S','trm','---','SO=','VLs','JMP',
- 'VL=','BRK','EFX','SPD');
-
- efx_txt : array[0..15] of string[4] = (
- 'filt','FPR^','FPRv','glis','vibf',
- 'FTUN','loop','trmf','PAN=','TRIG',
- 'FVL^','FVLv','NCUT','NDEL','pdel',
- 'funk');
-
- {$i adnpic.inc}
-
- var
- gusmem : longint;
- start_sample : integer;
-
- old_row : integer;
- mod_name : string;
- pause : byte;
- oldint8,oldint9 : procedure;
- alt_tab : boolean;
-
- procedure hide_cursor; assembler;
- asm
- mov ax,0100h
- mov cx,2607h
- int 10h
- end;
-
- procedure wait_vr; assembler;
- asm
- mov dx,3dah
- @@1:
- in al,dx
- test al,8
- jz @@1
- end;
-
- procedure wait_novr; assembler;
- asm
- mov dx,3dah
- @@1:
- in al,dx
- test al,8
- jnz @@1
- end;
-
- procedure setvgapal(pal,col1,col2,col3 : byte); assembler;
- asm
- mov dx,3c8h
- mov al,pal
- out dx,al
- inc dx
- mov al,col1
- out dx,al
- mov al,col2
- out dx,al
- mov al,col3
- out dx,al
- end;
-
- procedure set_scr_ofs(ofs : word); assembler;
- asm
- pushf
- cli
- mov bx,ofs
- mov dx,$3d4
- mov al,0Ch {Start address high}
- out dx,al
- inc dx
- mov al,bh
- out dx,al
- dec dx
- mov al,0Dh {Start address high}
- out dx,al
- inc dx
- mov al,bl
- out dx,al
- popf
- end;
-
- procedure line_comp(lc : word);
- var
- b : byte;
- begin
- port[$3d4] := 7;
- if lc and 256 > 0 then b := 31
- else b := 15;
- port[$3d5] := b;
- port[$3d4] := 9;
- port[$3d5] := 7;
- port[$3d4] := $18;
- port[$3d5] := lo(lc);
- end;
-
-
- {function keypressed : boolean;
- var
- b : byte;
- begin
- b := 0;
- asm
- mov ah,1
- int 16h
- jz @@1
- mov b,1
- @@1:
- end;
- if b = 0 then keypressed := false
- else keypressed := true;
- end;
-
- function readkey : char;
- var
- c : char;
- begin
- asm
- xor ax,ax
- int 16h
- mov c,al
- end;
- readkey := c;
- end;}
- {$s-}
- procedure fillattr(x,y,xl : integer; attr : byte); assembler;
- asm
- mov ax,0b800h
- mov es,ax
- mov di,y
- dec di
- mov ax,160
- mul di
- dec x
- add ax,x
- add ax,x
- mov di,ax
- inc di
- mov cx,xl
- mov al,attr
- @@1:
- mov es:[di],al
- add di,2
- loop @@1
- end;
-
- procedure fastwrite(x,y : word;s : string);
- begin
- {l := byte(s[0]);
- if l = 0 then exit;
- for n := 1 to l do mem[$b800:(y-1)*160+(x-1)*2+n*2-2] := byte(s[n]);}
- asm
- push ds
- mov ax,ss
- mov ds,ax
- mov ax,0b800h
- mov es,ax
- lea si,s
- lodsb
- cmp al,0
- jne @@2
- ret
- @@2:
- mov cl,al
- xor ch,ch
- mov di,y
- dec di
- dec x
- mov ax,160
- mul di
- mov di,ax
- add di,x
- add di,x
- @@1:
- movsb
- inc di
- loop @@1
- pop ds
- end;
- end;
-
- procedure fastwritel(x,y,l : word;s : string);
- begin
- asm
- push ds
- mov ax,ss
- mov ds,ax
- mov ax,0b800h
- mov es,ax
- lea si,s
- inc si
- mov cx,l
- cmp cx,0
- jne @@2
- ret
- @@2:
- mov di,y
- dec di
- dec x
- mov ax,160
- mul di
- mov di,ax
- add di,x
- add di,x
- @@1:
- movsb
- inc di
- loop @@1
- pop ds
- end;
- end;
-
- procedure scroll_up(y1,yl : word); assembler;
- asm
- mov ax,y1
- mov cx,160
- mul cx
- mov y1,ax
- push ds
- mov ax,0b800h
- mov ds,ax
- mov es,ax
- mov si,y1
- add si,160
- mov di,y1
- mov bx,yl
- @@1:
- mov cx,80
- rep movsw
- dec bx
- jnz @@1
- pop ds
- end;
-
- function byte2hex(b : byte) : string;
- begin
- byte2hex := hex_tbl[b shr 4]+hex_tbl[b and 15];
- end;
-
- function nibb2hex(b : byte) : char;
- begin
- nibb2hex := hex_tbl[b and 15];
- end;
-
- function int2str(i,n : integer) : string;
- var
- s : string;
- begin
- str(i:n,s);
- int2str := s;
- end;
-
- function word2str(i,n : word) : string;
- var
- s : string;
- begin
- str(i:n,s);
- word2str := s;
- end;
-
- procedure showbyte(x,y : integer;b : byte); assembler;
- asm
- dec y
- dec x
- mov ax,0b800h
- mov es,ax
- mov di,y
- mov ax,160
- mul di
- mov di,ax
- add di,x
- add di,x
- mov ah,0
- mov al,b
- mov cl,10
- div cl
- add ax,3030h
- mov es:[di],al
- add di,2
- mov es:[di],ah
- end;
-
- procedure showint3(x,y : integer;w : word); assembler;
- asm
- dec y
- dec x
- mov ax,0b800h
- mov es,ax
- mov di,y
- mov ax,160
- mul di
- mov di,ax
- add di,x
- add di,x
- mov ax,w
- mov cl,100
- div cl
- mov bx,ax
- add al,30h
- mov es:[di],al
- add di,2
- mov al,bh
- mov ah,0
- mov cl,10
- div cl
- add ax,3030h
- mov es:[di],al
- add di,2
- mov es:[di],ah
- end;
-
- procedure showhex(x,y : integer;b : byte);
- begin
- mem[$b800:(y-1)*160+2*x-2] := byte(hex_tbl[b shr 4]);
- mem[$b800:(y-1)*160+2*x] := byte(hex_tbl[b and 15]);
- end;
-
- {$s+}
- procedure show_pic; assembler;
- asm
- mov ax,0b800h
- mov es,ax
- mov dx,0
- mov ax,700h
- mov cx,0
- mov si,offset imagedata
- xor di,di
- @@start:
- lodsb
- cmp al,8
- jae @@char
- cmp al,0
- je @@end
- cmp al,1
- je @@attr
- cmp al,2
- je @@pack
- cmp al,3
- je @@space
- jmp @@start
- @@attr:
- lodsb
- mov ah,al
- jmp @@start
- @@space:
- lodsb
- mov cl,al
- mov al,32
- rep stosw
- jmp @@start
- @@pack:
- lodsb
- mov cl,al
- lodsb
- rep stosw
- jmp @@start
- @@char:
- stosw
- jmp @@start
- @@end:
- end;
-
- function per2note(per : word) : string;
- var
- n,n2 : integer;
- s : string[3];
- begin
- n2 := 0;
- for n := 1 to 48 do begin
- if per_table[0,n] = per then begin
- n2 := n;
- n := 48;
- end;
- end;
- if n2 = 0 then if per = 0 then per2note := '...'
- else per2note := '???'
- else per2note := per_txt[n2];
- end;
-
- procedure show_sample(sam,x,y : integer);
- begin
- fastwrite(x,y,int2str(sam,2));
- fastwritel(x+4,y,22,samples[sam].name);
- fastwrite(x+31,y,word2str(samples[sam].length,5));
- fastwrite(x+39,y,word2str(samples[sam].loopstart,5));
- fastwrite(x+47,y,word2str(samples[sam].loopend,5));
- if samples[sam].ftune > 7 then
- fastwrite(x+55,y,int2str(samples[sam].ftune or $fff0,2))
- else fastwrite(x+55,y,int2str(samples[sam].ftune,2));
- fastwrite(x+61,y,int2str(samples[sam].volume,2));
- end;
- {$s-}
- procedure bar(x,y,l : integer;c : char); assembler;
- asm
- mov ax,0b800h
- mov es,ax
- mov di,y
- dec di
- mov ax,160
- mul di
- dec x
- add ax,x
- add ax,x
- mov di,ax
- cmp l,0
- jz @@3
- mov cx,l
- mov al,c
- @@1:
- stosb
- inc di
- dec cx
- jnz @@1
- @@3:
- mov cx,17
- sub cx,l
- mov al,32
- @@2:
- stosb
- inc di
- dec cx
- jnz @@2
- end;
-
- procedure show_chn(chn,st : byte);
- var
- fx,fxdata : byte;
- start : integer;
- begin
- start := 5-st;
- inc(chn,st);
- fx := channels[chn].fx;
- fxdata := channels[chn].fxdata;
- if channels[chn].on = 1 then
- fastwritel(3,chn+start,22,samples[channels[chn].sample].name)
- else fastwritel(3,chn+start,22,' ---MUTED--- ');
- fastwrite(30,chn+start,int2str(channels[chn].vol,2));
- fastwritel(34,chn+start,3,per_txt[channels[chn].note]);
- fastwrite(38,chn+start,int2str(channels[chn].per,3));
- fastwrite(43,chn+start,int2str(channels[chn].dper,3));
- fastwrite(54,chn+start,int2str(channels[chn].pan-7,2));
- if fx = 14 then
- fastwritel(47,chn+start,5,efx_txt[fxdata shr 4]+nibb2hex(fxdata and 15))
- else if ((fx < 16) and (fx >0)) or ((fx = 0) and (fxdata > 0)) then
- fastwritel(47,chn+start,5,fx_txt[fx]+byte2hex(fxdata))
- else fastwritel(47,chn+start,5,' ');
- bar(61,chn+start,(channels[chn].bar+2) div 4,'≈');
- if channels[chn].hit = 1 then begin
- fillattr(3,chn+start,22,15);
- fillattr(30,chn+start,26,15);
- end else begin
- fillattr(3,chn+start,22,7);
- fillattr(30,chn+start,26,7);
- end;
- channels[chn].hit := 0;
- end;
- {$s+}
-
- procedure show_ptn(start_chn : integer;clear : boolean);
- var
- ptn : word;
-
- procedure show_row(row : integer);
- const
- wid = 16;
- x = 11;
- var
- n : integer;
- sam : integer;
- fx,fxdata : byte;
- chn : integer;
- begin
- fastwrite(8,26,byte2hex(row)+':');
-
- for n := 0 to 3 do begin
- chn := start_chn+n;
- fastwrite(n*wid+x+2,26,per2note(patterns[ptn]^[row,chn].per)+' ');
- sam := patterns[ptn]^[row,chn].sample;
- if sam > 0 then fastwrite(n*wid+x+6,26,byte2hex(sam)+' ')
- else fastwrite(n*wid+x+6,26,'.. ');
- fx := patterns[ptn]^[row,chn].fx;
- fxdata := patterns[ptn]^[row,chn].fxdata;
- case fx of
- 0 : if fxdata > 0 then
- fastwrite(n*wid+x+9,26,fx_txt[fx]+byte2hex(fxdata))
- else fastwrite(n*wid+x+9,26,' ');
- 1..$D : fastwrite(n*wid+x+9,26,fx_txt[fx]+byte2hex(fxdata));
- $E : fastwrite(n*wid+x+9,26,efx_txt[fxdata shr 4]+nibb2hex(fxdata and 15));
- $F : fastwrite(n*wid+x+9,26,fx_txt[fx]+byte2hex(fxdata));
- else fastwrite(n*wid+x+9,26,' ');
- end;
- end;
- end;
-
- procedure show_info;
- begin
- fastwrite(30,12,int2str(amp_vol,2));
- fastwrite(41,12,int2str(speed,2));
- if not vblank then fastwrite(53,12,int2str(tempo,3)+' ')
- else fastwrite(53,12,'VBlank');
- fastwrite(30,13,int2str(cur_ptn,2)+'/'+int2str(header.length-1,2));
- fastwrite(41,13,int2str(ptn,2)+'/'+int2str(max_ptn-1,2));
- fastwrite(53,13,int2str(cur_row,2));
- end;
-
- var
- i : integer;
- kbf : byte;
- s : string;
- begin
- fastwritel(30,11,20,header.name);
- for i := 0 to 20 do show_sample(i+start_sample,9,i+30);
- if clear then begin
- s := ' ';
- for i := 0 to 7 do fastwritel(8,18+i,65,s);
- end;
- repeat
- ptn := orders[cur_ptn];
- wait_vr;
- kbf := mem[$40:$17] and 15;
- if channels[start_chn].hit=1 then kbf := kbf or $20;
- if channels[start_chn+1].hit=1 then kbf := kbf or $40;
- if channels[start_chn+2].hit=1 then kbf := kbf or $10;
- mem[$40:$17] := kbf;
- for i := 0 to 3 do show_chn(i,start_chn);
- show_info;
- time_counter2 := 0;
- if cur_row <> old_row then begin
- old_row := cur_row;
- fillattr(13,26,60,7+2*16);
- scroll_up(17,8);
- show_row(cur_row);
- fillattr(13,26,60,15+2*16);
- end;
- until keypressed;
- mem[$40:$17] := mem[$40:$17] and 15;
- end;
-
- {$s-,i-}
- procedure int9; interrupt;
- begin
- if (mem[$40:$17] and 8 > 0) and (port[$60] = $f) then
- if alt_tab then begin
- alt_tab := false;
- end
- else begin
- alt_tab := true;
- end;
- asm pushf end;
- oldint9;
- end;
-
- procedure fwritel(x,y,l : integer;s : pointer); assembler;
- asm
- push ds
- mov ax,word ptr s+2
- mov ds,ax
- mov ax,0b800h
- mov es,ax
- mov si,word ptr s
- inc si
- mov cx,l
- cmp cx,0
- jne @@2
- ret
- @@2:
- mov di,y
- dec di
- dec x
- mov ax,160
- mul di
- mov di,ax
- add di,x
- add di,x
- @@1:
- movsb
- inc di
- loop @@1
- pop ds
- end;
-
- procedure int8; interrupt;
- var
- n : integer;
- p : longint;
- fx,fxdata : byte;
- begin
- asm pushf end;
- oldint8;
- if alt_tab then begin
- showbyte(53,13+50,cur_row);
- showbyte(41,12+50,speed);
- showbyte(30,13+50,cur_ptn);
- showbyte(33,13+50,header.length-1);
- showbyte(41,13+50,orders[cur_ptn]);
- showbyte(44,13+50,max_ptn-1);
- for n := 0 to 3 do begin
- fx := channels[n].fx;
- fxdata := channels[n].fxdata;
- p := longint(@samples[channels[n].sample].name)-1;
- fwritel(3,n+55,22,pointer(p));
- showbyte(30,n+55,channels[n].vol);
- fwritel(34,n+55,3,@per_txt[channels[n].note]);
- showint3(38,n+55,channels[n].per);
- showint3(43,n+55,channels[n].dper);
- if fx = 14 then begin
- showhex(50,n+55,fxdata and 15);
- fwritel(47,n+55,4,@efx_txt[fxdata shr 4]);
- end
- else if (fx < 16) and (fx >0) then begin
- fwritel(47,n+55,3,@fx_txt[fx]);
- showhex(50,n+55,fxdata);
- end;
- if fx > 15 then fillchar(mem[$b800:(n+54)*160+46*2],10,0);
- bar(61,55+n,(channels[n].bar+2) div 4,'≈');
- if channels[n].hit = 1 then begin
- fillattr(3,n+55,22,15);
- fillattr(30,n+55,26,15);
- end else begin
- fillattr(3,n+55,22,7);
- fillattr(30,n+55,26,7);
- end;
- end;
- end;
- end;
- {$s+,i+}
-
- procedure init_dos;
- begin
- alt_tab := true;
- getintvec(9,@oldint9);
- getintvec(8,@oldint8);
- asm
- cld
- push ds
- mov ax,0B800h
- mov es,ax
- mov ds,ax
- mov si,0
- mov di,8000
- mov cx,80*13
- rep movsw
- pop ds
-
- mov di,0
- mov cx,4000
- mov ax,0720h
- rep stosw
- end;
- mem[$40:$84] := 36;
- set_scr_ofs(4000);
- line_comp(13*8);
- setintvec(8,@int8);
- setintvec(9,@int9);
- end;
-
- procedure end_dos;
- begin
- setintvec(8,@oldint8);
- setintvec(9,@oldint9);
- end;
-
- procedure play_sample(n : integer);
- begin
- mem[$b800:0] := n+byte('0');
- gussetfreq(10,periods[per_table[samples[n].ftune,24]]);
- gussetvolume(10,gusvol[64]*amp_vol);
- if samples[n].loopend > 2 then
- gusplayvoice(10,8,gus_addr[n]+2,
- gus_addr[n]+samples[n].loopstart,
- gus_addr[n]+samples[n].loopend)
- else gusplayvoice(10,2,gus_addr[n]+2,
- gus_addr[n]+2,
- gus_addr[n]+samples[n].length);
-
- end;
-
- procedure menu;
- var
- ch : char;
- playing,clr : boolean;
- start_chn : integer;
- begin
- clr := true;
- start_chn := 0;
- pause := 0;
- old_row := 666;
- start_sample := 1;
- hide_cursor;
- setvgapal(col_back,col_backr,col_backg,col_backb);
- show_pic;
- playing := true;
- start_playing;
- repeat
- show_ptn(start_chn,clr);
- clr := false;
- ch := readkey;
- case ch of
- '+' : if amp_vol < 18 then inc(amp_vol);
- '-' : if amp_vol > 0 then dec(amp_vol);
- '<' : if start_sample > 1 then dec(start_sample);
- '>' : if start_sample < 11 then inc(start_sample);
- ',' : if start_chn > 0 then begin
- dec(start_chn);
- clr := true;
- end;
- '.' : if start_chn < header.chns-4 then begin
- inc(start_chn);
- clr := true;
- end;
- 'p' : if pause = 0 then begin
- pause := speed;
- speed := 0;
- end else begin
- speed := pause;
- pause := 0;
- end;
- 'r' : if playing then begin
- stop_playing;
- playing := false;
- end else begin
- clr := true;
- start_playing;
- playing := true;
- end;
- 'v' : if vblank then vblank := false
- else vblank := true;
- #8 : begin {bkspc}
- jump := 1;
- new_ptn := cur_ptn;
- new_row := 0;
- clr := true;
- end;
- #0 : begin
- ch := readkey;
- case ch of
- #81 : if speed < 31 then begin {pgdn}
- inc(nspeed);
- inc(speed);
- end;
- #73 : if speed > 0 then begin {pgup}
- dec(nspeed);
- dec(speed);
- end;
- #59..#66 : if byte(ch)-59 < header.chns then begin {F1-F8}
- channels[byte(ch)-59].on :=
- channels[byte(ch)-59].on xor 1;
- gusstopvoice(byte(ch)-58);
- end;
- #75 : begin {left arrow}
- jump := 1;
- if cur_ptn > 0 then new_ptn := cur_ptn-1;
- new_row := 0;
- clr := true;
- end;
- #77 : begin {right arrow}
- jump := 1;
- if cur_ptn < header.length-1 then
- new_ptn := cur_ptn+1;
- new_row := 0;
- clr := true;
- end;
- end;
- end;
- '!' : begin
- textmode(co80);
- exec(getenv('COMSPEC'),'');
- textmode(co80+font8x8);
- hide_cursor;
- setvgapal(col_back,col_backr,col_backg,col_backb);
- show_pic;
- old_row := 666;
- end;
- '"' : begin
- init_dos;
- exec(getenv('COMSPEC'),'');
- end_dos;
- textmode(co80+font8x8);
- hide_cursor;
- setvgapal(col_back,col_backr,col_backg,col_backb);
- show_pic;
- old_row := 666;
- end;
- end;
- until ch = #27;
- stop_playing;
- end;
-
- function exists(s : string) : boolean;
- var
- f : file of byte;
- i : integer;
- begin
- assign(f,s);
- {$i-}
- reset(f);
- i := ioresult;
- {$i+}
- if i = 0 then begin
- close(f);
- exists := true;
- end else exists := false;
- end;
-
- function addext(str,ext: string) : string;
- begin
- if pos('.',str) > 0 then addext := str
- else addext := str+ext;
- end;
-
- function findgus : word;
- var
- n,c,i : word;
- begin
- if getenv('ultrasnd') = '' then begin
- findgus := 0;
- exit;
- end;
- val(copy(getenv('ultrasnd'),1,3),n,c);
- if c <> 0 then begin
- findgus := 0;
- exit;
- end;
- case n of
- 210 : i := $210;
- 220 : i := $220;
- 230 : i := $230;
- 240 : i := $240;
- 250 : i := $250;
- 260 : i := $260;
- 270 : i := $270;
- else begin
- findgus := 0;
- exit;
- end;
- end;
- findgus := i;
- end;
-
- procedure getcmd;
- var
- s : string;
- begin
- writeln('Adrenalin module player v 0.2 By: Beta/Adrenalin');
- if paramcount < 1 then begin
- writeln('Usage: ADNMOD modname [/port]');
- halt(0);
- end;
- s := addext(paramstr(1),'.mod');
- if not exists(s) then begin
- writeln('Module ',s,' not found!');
- halt(2);
- end;
- mod_name := s;
- if (paramcount > 1) and (copy(paramstr(2),1,1) = '/') then begin
- s := copy(paramstr(2),2,3);
- if s = '210' then base := $210;
- if s = '220' then base := $220;
- if s = '230' then base := $230;
- if s = '240' then base := $240;
- if s = '250' then base := $250;
- if s = '260' then base := $260;
- if s = '270' then base := $270;
- end;
- end;
-
- begin
- checkbreak := false;
- getcmd;
- if base = $200 then if findgus > 0 then base := findgus;
- gusfind;
- if base = $200 then begin
- writeln('GUS not found. Assuming address 220');
- base := $220;
- gusfind;
- end;
- write('GUS found at ',nibb2hex(hi(base)),byte2hex(lo(base)));
- gusmem := gusfindmem;
- writeln(' with ',gusmem,' bytes of memory');
- gusreset;
- init_mod;
- load_mod(mod_name,true);
- if mod_error <> 0 then case mod_error of
- 1 : begin
- writeln('Too many channels');
- halt(1);
- end;
- 2 : begin
- writeln;
- writeln('Load error!');
- halt(2);
- end;
- 3 : begin
- writeln;
- writeln('Out of memory');
- halt(2);
- end;
- 255 : begin
- writeln('Error');
- halt(3);
- end;
- end;
- textmode(co80+font8x8);
- menu;
- free_mod;
- gusdeinit;
- textmode(co80);
- end.
-
-